using System;
using System.Collections.Generic;
using System.IO;
using Game.Component;
using Game.Core;
using Game.Manager;
using Game.Utils;
using SimpleJSON;
using UnityEngine;

namespace Game.Main.Model
{
	public class SceneModel : Singleton<SceneModel>
	{
		private const string MAP_ID = "mapId";

		private const string MAP_BASIC_DATA = "mapBasicData";

		private const string CAMERA_X = "cameraX";

		private const string MAX_ITEM_INDEX = "maxItemIndex";

		private const uint MIN_INDEX = 1000u;

		public ComposeData[] composeConfig;

		public ItemData[] itemConfig;

		public MapData[] mapConfig;

		public Dictionary<int, float> mapBasicData = new Dictionary<int, float>();

		public Dictionary<int, List<ItemArchiveData>> mapsData = new Dictionary<int, List<ItemArchiveData>>();

		public List<ItemArchiveData> itemArchiveData = new List<ItemArchiveData>();

		public List<ItemArchiveData> storageboxData = new List<ItemArchiveData>();

		public List<ItemArchiveData> elevatorData = new List<ItemArchiveData>();

		public List<ItemArchiveData> ambulanceData = new List<ItemArchiveData>();

		public List<int> needUpdateMapIds = new List<int>();

		public bool isEmptyScene;

		public bool isSBArchiveExist;

		public uint maxItemIndex;

		public float cameraX;

		public bool isElevatorTransfer;

		public bool isAmbulanceTransfer;

		public float mapViewScrollX = -2.1474836E+09f;

		public SceneModel()
		{
			InitMapConfig();
		}

		public void InitData()
		{
			isEmptyScene = true;
			isSBArchiveExist = false;
			itemArchiveData.Clear();
			needUpdateMapIds.Clear();
		}

		public void InitMapConfig()
		{
			mapConfig = new MapData[6];
			mapConfig[0] = new MapData(1, 0f, 0f, 19.6f);
			mapConfig[1] = new MapData(2, 0f, 0f, 25.179f);
			mapConfig[2] = new MapData(3, 0f, 0f, 30.346f);
			mapConfig[3] = new MapData(4, 0f, 0f, 12.6f);
			mapConfig[4] = new MapData(5, 0f, 0f, 34.75f);
			mapConfig[5] = new MapData(6, 0f, 0f, 20.9f);
		}

		public void ParseComposeConfig(MemoryStream ms)
		{
			int num = ParseUtil.ReadInt32(ms);
			composeConfig = new ComposeData[num];
			for (int i = 0; i < num; i++)
			{
				ComposeData composeData = new ComposeData();
				composeData.id1 = ParseUtil.ReadString(ms);
				composeData.id2 = ParseUtil.ReadString(ms);
				composeData.id3 = ParseUtil.ReadString(ms);
				composeConfig[i] = composeData;
			}
		}

		public List<ComposeData> GetComposeData(string id)
		{
			List<ComposeData> list = null;
			for (int i = 0; i < composeConfig.Length; i++)
			{
				if (composeConfig[i].id1.Equals(id) || composeConfig[i].id2.Equals(id))
				{
					if (list == null)
					{
						list = new List<ComposeData>();
					}
					list.Add(composeConfig[i]);
				}
			}
			return list;
		}

		public void ParseItemConfig(MemoryStream ms)
		{
			int num = ParseUtil.ReadInt32(ms);
			itemConfig = new ItemData[num];
			for (int i = 0; i < num; i++)
			{
				ItemData itemData = new ItemData();
				itemData.id = ParseUtil.ReadString(ms);
				itemData.type = ParseUtil.ReadByte(ms);
				itemData.layer = ParseUtil.ReadByte(ms);
				itemData.name = ParseUtil.ReadString(ms);
				itemData.model = ParseUtil.ReadString(ms);
				itemData.scale = ParseUtil.ReadFloat32(ms);
				itemData.scriptType = ParseUtil.ReadByte(ms);
				itemData.canEat = ParseUtil.ReadBool(ms);
				itemData.canSit = ParseUtil.ReadBool(ms);
				itemData.sitType = ParseUtil.ReadByte(ms);
				itemData.lieType = ParseUtil.ReadByte(ms);
				itemData.placeType = ParseUtil.ReadInt32(ms);
				itemData.placeAttachType = ParseUtil.ReadInt32(ms);
				itemData.placeSortType = ParseUtil.ReadInt32(ms);
				itemData.canPlaceTypes = ParseUtil.ReadInt32Array(ms);
				itemData.placeAmount = ParseUtil.ReadInt32(ms);
				itemData.checkDirType = ParseUtil.ReadByte(ms);
				itemData.canDrag = ParseUtil.ReadBool(ms);
				itemData.dragX = ParseUtil.ReadFloat32(ms);
				itemData.dragY = ParseUtil.ReadFloat32(ms);
				itemData.dragAngle = ParseUtil.ReadInt32(ms);
				itemData.dragEfc = ParseUtil.ReadString(ms);
				itemData.dragSound = ParseUtil.ReadStringArray(ms);
				itemData.effect = ParseUtil.ReadString(ms);
				itemData.clickSound = ParseUtil.ReadStringArray(ms);
				itemData.quicklyClickSound = ParseUtil.ReadStringArray(ms);
				itemData.canHold = ParseUtil.ReadBool(ms);
				itemData.holdX = ParseUtil.ReadFloat32(ms);
				itemData.holdY = ParseUtil.ReadFloat32(ms);
				itemData.holdAngle = ParseUtil.ReadInt32(ms);
				itemData.holdFlip = ParseUtil.ReadBool(ms);
				itemData.canPutHead = ParseUtil.ReadBool(ms);
				itemData.putHeadX = ParseUtil.ReadFloat32(ms);
				itemData.putHeadY = ParseUtil.ReadFloat32(ms);
				itemData.putHeadAngle = ParseUtil.ReadInt32(ms);
				itemData.hideHair = ParseUtil.ReadBool(ms);
				itemData.hideTops = ParseUtil.ReadBool(ms);
				itemData.hidePants = ParseUtil.ReadBool(ms);
				itemData.hideShoes = ParseUtil.ReadBool(ms);
				itemData.canPutFace = ParseUtil.ReadBool(ms);
				itemData.putFaceX = ParseUtil.ReadFloat32(ms);
				itemData.putFaceY = ParseUtil.ReadFloat32(ms);
				itemData.putFaceAngle = ParseUtil.ReadInt32(ms);
				itemData.canPutBody = ParseUtil.ReadBool(ms);
				itemData.putBodyX = ParseUtil.ReadFloat32(ms);
				itemData.putBodyY = ParseUtil.ReadFloat32(ms);
				itemData.putBodyAngle = ParseUtil.ReadInt32(ms);
				itemData.canPutHand = ParseUtil.ReadBool(ms);
				itemData.putHandX = ParseUtil.ReadFloat32(ms);
				itemData.putHandY = ParseUtil.ReadFloat32(ms);
				itemData.putHandAngle = ParseUtil.ReadInt32(ms);
				itemData.putHandFlip = ParseUtil.ReadBool(ms);
				itemData.canPutLeg = ParseUtil.ReadBool(ms);
				itemData.putLegX = ParseUtil.ReadFloat32(ms);
				itemData.putLegY = ParseUtil.ReadFloat32(ms);
				itemData.putLegAngle = ParseUtil.ReadInt32(ms);
				itemData.canDestroy = ParseUtil.ReadBool(ms);
				itemData.headId = ParseUtil.ReadInt32(ms);
				itemData.hairId = ParseUtil.ReadInt32(ms);
				itemData.bodyId = ParseUtil.ReadInt32(ms);
				itemData.topsId = ParseUtil.ReadInt32(ms);
				itemData.topsIconId = ParseUtil.ReadInt32(ms);
				itemData.pantsId = ParseUtil.ReadInt32(ms);
				itemData.shoesId = ParseUtil.ReadInt32(ms);
				itemData.browId = ParseUtil.ReadInt32(ms);
				itemData.eyeId = ParseUtil.ReadInt32(ms);
				itemData.noseId = ParseUtil.ReadInt32(ms);
				itemData.mouthId = ParseUtil.ReadInt32(ms);
				itemData.featureId = ParseUtil.ReadInt32(ms);
				itemData.normalAngle = ParseUtil.ReadInt32(ms);
				itemData.parentAngleTyes = ParseUtil.ReadInt32Array(ms);
				itemData.parentAngles = ParseUtil.ReadInt32Array(ms);
				itemData.hairColor = new Color32(ParseUtil.ReadByte(ms), ParseUtil.ReadByte(ms), ParseUtil.ReadByte(ms), byte.MaxValue);
				itemData.bodyColor = new Color32(ParseUtil.ReadByte(ms), ParseUtil.ReadByte(ms), ParseUtil.ReadByte(ms), byte.MaxValue);
				itemData.color = new Color32(ParseUtil.ReadByte(ms), ParseUtil.ReadByte(ms), ParseUtil.ReadByte(ms), byte.MaxValue);
				itemData.scriptParams = ParseUtil.ReadString(ms);
				itemData.createIds = ParseUtil.ReadStringArray(ms);
				itemData.createAmount = ParseUtil.ReadInt32(ms);
				itemData.changeId = ParseUtil.ReadString(ms);
				itemData.tyreId = ParseUtil.ReadByte(ms);
				itemData.state = ParseUtil.ReadInt32(ms);
				itemData.canFlip = ParseUtil.ReadBool(ms);
				itemData.canBurn = ParseUtil.ReadBool(ms);
				itemData.forceStand = ParseUtil.ReadBool(ms);
				itemData.collForceFront = ParseUtil.ReadBool(ms);
				itemData.floatType = ParseUtil.ReadByte(ms);
				itemData.floatWaterHeight = ParseUtil.ReadFloat32(ms);
				itemData.dontPutOtherScene = ParseUtil.ReadBool(ms);
				itemData.canTouch = ParseUtil.ReadBool(ms);
				itemData.lockCamera = ParseUtil.ReadBool(ms);
				itemData.isPoison = ParseUtil.ReadBool(ms);
				itemData.holdType = ParseUtil.ReadByte(ms);
				itemConfig[i] = itemData;
			}
		}

		public ItemData GetItemData(string id)
		{
			for (int i = 0; i < itemConfig.Length; i++)
			{
				ItemData itemData = itemConfig[i];
				if (itemData.id.Equals(id))
				{
					return itemData;
				}
			}
			return null;
		}

		public ItemData GetItemDataByTyreId(int id)
		{
			for (int i = 0; i < itemConfig.Length; i++)
			{
				ItemData itemData = itemConfig[i];
				if (itemData.scriptType == 25 && itemData.tyreId == id)
				{
					return itemData;
				}
			}
			return null;
		}

		public ItemData GetClothingDataByTopsId(int id)
		{
			if (id == 0)
			{
				return null;
			}
			for (int i = 0; i < itemConfig.Length; i++)
			{
				ItemData itemData = itemConfig[i];
				if (itemData.scriptType == 14 && itemData.topsId == id)
				{
					return itemData;
				}
			}
			return null;
		}

		public ItemData GetBabyClothingDataByTopsId(int id)
		{
			if (id == 0)
			{
				return null;
			}
			for (int i = 0; i < itemConfig.Length; i++)
			{
				ItemData itemData = itemConfig[i];
				if (itemData.scriptType == 163 && itemData.topsId == id)
				{
					return itemData;
				}
			}
			return null;
		}

		public ItemData GetItemDataByPantsId(int id)
		{
			if (id == 0)
			{
				return null;
			}
			for (int i = 0; i < itemConfig.Length; i++)
			{
				ItemData itemData = itemConfig[i];
				if (itemData.scriptType == 14 && itemData.pantsId == id)
				{
					return itemData;
				}
			}
			return null;
		}

		public ItemData GetItemDataByShoesId(int id)
		{
			for (int i = 0; i < itemConfig.Length; i++)
			{
				ItemData itemData = itemConfig[i];
				if (itemData.scriptType == 15 && itemData.shoesId == id)
				{
					return itemData;
				}
			}
			return null;
		}

		public void CheckRedundantData(int mapId, uint index, RedundantData.DataType type, uint relateIndex)
		{
			foreach (KeyValuePair<int, List<ItemArchiveData>> mapsDatum in mapsData)
			{
				if (mapId == mapsDatum.Key || mapsDatum.Value == null)
				{
					continue;
				}
				List<ItemArchiveData> value = mapsDatum.Value;
				for (int i = 0; i < value.Count; i++)
				{
					ItemArchiveData itemArchiveData = value[i];
					if (itemArchiveData.index == index)
					{
						switch (type)
						{
						case RedundantData.DataType.CreateIndex:
							itemArchiveData.createIndexs.Remove(relateIndex);
							break;
						case RedundantData.DataType.CreateParentIndex:
							itemArchiveData.createParentIndex = 0u;
							break;
						}
						if (!needUpdateMapIds.Contains(mapsDatum.Key))
						{
							needUpdateMapIds.Add(mapsDatum.Key);
						}
						return;
					}
				}
			}
		}

		public void SaveArchiveData(int mapId, List<BaseItem> items, float cameraX, uint maxItemIndex)
		{
			bool flag = false;
			bool flag2 = false;
			for (int i = 0; i < items.Count; i++)
			{
				BaseItem baseItem = items[i];
				if (baseItem != null)
				{
					if (baseItem.transform == null)
					{
						Debug.LogError(baseItem.itemData.id + " 对象丢失");
						LoadOtherArchiveData();
						return;
					}
					if (!flag && baseItem.itemData.scriptType == 73)
					{
						flag = true;
					}
					if (!flag2 && baseItem.itemData.scriptType == 153)
					{
						flag2 = true;
					}
					baseItem.CheckCanPutOtherScene();
					continue;
				}
				Debug.LogError("地图" + mapId + "对象丢失，前一个物件序号为：" + (i - 1));
				LoadOtherArchiveData();
				return;
			}
			JSONArray jSONArray = new JSONArray();
			JSONArray jSONArray2 = new JSONArray();
			JSONArray jSONArray3 = new JSONArray();
			JSONArray jSONArray4 = new JSONArray();
			for (int j = 0; j < items.Count; j++)
			{
				BaseItem baseItem2 = items[j];
				JSONObject jSONObject = new JSONObject();
				baseItem2.PackData(jSONObject);
				if (baseItem2.archiveData.layer == 9 || baseItem2.itemData.scriptType == 1 || baseItem2.ParentIsCharacter())
				{
					jSONArray2.Add(jSONObject);
				}
				else if (flag && baseItem2.archiveData.mapId == 101)
				{
					jSONArray3.Add(jSONObject);
				}
				else if (flag2 && baseItem2.archiveData.mapId == 102)
				{
					jSONArray4.Add(jSONObject);
				}
				else
				{
					jSONArray.Add(jSONObject);
				}
			}
			if (jSONArray.Count < 1)
			{
				Debug.LogError("ArchiveData is Error");
				return;
			}
			string data = jSONArray.ToString();
			Singleton<SaveManager>.Instance.SaveMapArchive(mapId, data);
			string text = jSONArray2.ToString();
			Singleton<SaveManager>.Instance.SaveStorageBoxArchive(text);
			if (flag)
			{
				string data2 = jSONArray3.ToString();
				Singleton<SaveManager>.Instance.SaveElevatorArchive(data2);
				elevatorData.Clear();
				ParseItemArchiveData(data2, elevatorData);
			}
			if (flag2)
			{
				string data3 = jSONArray4.ToString();
				Singleton<SaveManager>.Instance.SaveAmbulanceArchive(data3);
				ambulanceData.Clear();
				ParseItemArchiveData(data3, ambulanceData);
			}
			List<ItemArchiveData> list = new List<ItemArchiveData>();
			ParseItemArchiveData(data, list);
			if (mapsData.ContainsKey(mapId))
			{
				mapsData[mapId].Clear();
				mapsData[mapId] = list;
			}
			else
			{
				mapsData.Add(mapId, list);
			}
			if (!string.IsNullOrEmpty(text))
			{
				storageboxData.Clear();
				ParseItemArchiveData(text, storageboxData);
			}
			for (int k = 0; k < needUpdateMapIds.Count; k++)
			{
				int num = needUpdateMapIds[k];
				if (num != mapId && mapsData.ContainsKey(num))
				{
					JSONArray jSONArray5 = new JSONArray();
					List<ItemArchiveData> list2 = mapsData[num];
					for (int l = 0; l < list2.Count; l++)
					{
						JSONObject jSONObject2 = new JSONObject();
						list2[l].PackData(jSONObject2);
						jSONArray5.Add(jSONObject2);
					}
					Singleton<SaveManager>.Instance.SaveMapArchive(num, jSONArray5.ToString());
				}
			}
			JSONObject jSONObject3 = new JSONObject();
			jSONObject3["maxItemIndex"] = maxItemIndex;
			JSONArray jSONArray6 = (JSONArray)(jSONObject3["mapBasicData"] = new JSONArray());
			if (!mapBasicData.ContainsKey(mapId))
			{
				mapBasicData.Add(mapId, cameraX);
			}
			else
			{
				mapBasicData[mapId] = cameraX;
			}
			foreach (KeyValuePair<int, float> mapBasicDatum in mapBasicData)
			{
				JSONObject jSONObject4 = new JSONObject();
				jSONObject4["mapId"] = mapBasicDatum.Key;
				jSONObject4["cameraX"] = mapBasicDatum.Value;
				jSONArray6.Add(jSONObject4);
			}
			Singleton<SaveManager>.Instance.SaveMapBasicData(jSONObject3.ToString());
		}

		public void LoadArchiveData()
		{
			mapsData.Clear();
			for (int i = 0; i < mapConfig.Length; i++)
			{
				MapData mapData = mapConfig[i];
				byte[] array = Singleton<SaveManager>.Instance.LoadMapArchive(mapData.id);
				if (array != null)
				{
					mapsData.Add(mapData.id, ParseItemArchiveData(array));
				}
			}
			LoadOtherArchiveData();
		}

		private void LoadOtherArchiveData()
		{
			byte[] array = Singleton<SaveManager>.Instance.LoadStorageBoxArchive();
			if (array != null)
			{
				storageboxData = ParseItemArchiveData(array);
			}
			else
			{
				storageboxData.Clear();
			}
			array = Singleton<SaveManager>.Instance.LoadElevatorArchive();
			if (array != null)
			{
				elevatorData = ParseItemArchiveData(array);
			}
			else
			{
				elevatorData.Clear();
			}
			array = Singleton<SaveManager>.Instance.LoadAmbulanceArchive();
			if (array != null)
			{
				ambulanceData = ParseItemArchiveData(array);
			}
			else
			{
				ambulanceData.Clear();
			}
			array = Singleton<SaveManager>.Instance.LoadMapBasicData();
			mapBasicData.Clear();
			if (array != null)
			{
				string text = Compressor.UnCompress(array);
				if (!string.IsNullOrEmpty(text))
				{
					JSONObject asObject = JSONNode.Parse(text).AsObject;
					maxItemIndex = uint.Parse(asObject["maxItemIndex"]);
					JSONArray jSONArray = asObject["mapBasicData"] as JSONArray;
					for (int i = 0; i < jSONArray.Count; i++)
					{
						JSONObject jSONObject = jSONArray[i] as JSONObject;
						mapBasicData.Add(jSONObject["mapId"], jSONObject["cameraX"]);
					}
				}
			}
			else
			{
				maxItemIndex = 0u;
			}
			if (maxItemIndex < 1000)
			{
				maxItemIndex = 1000u;
			}
		}

		private List<ItemArchiveData> ParseItemArchiveData(byte[] bytes)
		{
			string data = Compressor.UnCompress(bytes);
			List<ItemArchiveData> list = new List<ItemArchiveData>();
			ParseItemArchiveData(data, list);
			return list;
		}

		public void ResetArchiveData()
		{
			itemArchiveData.Clear();
			mapsData.Clear();
			storageboxData.Clear();
			ambulanceData.Clear();
			elevatorData.Clear();
			maxItemIndex = 1000u;
			mapBasicData.Clear();
			Singleton<SaveManager>.Instance.ClearArchive();
		}

		public void LoadArchiveData(int mapId)
		{
			if (mapsData.ContainsKey(mapId))
			{
				itemArchiveData = mapsData[mapId];
				isEmptyScene = false;
			}
			else
			{
				isEmptyScene = true;
			}
			if (storageboxData.Count > 0)
			{
				isSBArchiveExist = true;
			}
			else
			{
				isSBArchiveExist = false;
			}
			if (mapBasicData.ContainsKey(mapId))
			{
				cameraX = mapBasicData[mapId];
			}
			else
			{
				cameraX = 0f;
				for (int i = 0; i < mapConfig.Length; i++)
				{
					MapData mapData = mapConfig[i];
					if (mapData.id == mapId)
					{
						cameraX = mapData.cameraX;
						break;
					}
				}
			}
			needUpdateMapIds.Clear();
		}

		private void ParseItemArchiveData(string data, List<ItemArchiveData> list)
		{
			try
			{
				JSONArray asArray = JSONNode.Parse(data).AsArray;
				for (int i = 0; i < asArray.Count; i++)
				{
					JSONObject asObject = asArray[i].AsObject;
					ItemData itemData = GetItemData(asObject["1"]);
					if (itemData != null)
					{
						list.Add(BaseItem.UnpackData(asObject, itemData));
					}
					else
					{
						Debug.LogError(string.Concat("ID：", asObject["1"], "的物件不存在！"));
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogError(string.Concat("存档数据异常：", ex, "  ->  ", data));
			}
		}

		public ItemArchiveData GetItemArchiveData(string id)
		{
			for (int i = 0; i < this.itemArchiveData.Count; i++)
			{
				ItemArchiveData itemArchiveData = this.itemArchiveData[i];
				if (itemArchiveData.itemData.id.Equals(id))
				{
					return itemArchiveData;
				}
			}
			for (int j = 0; j < storageboxData.Count; j++)
			{
				ItemArchiveData itemArchiveData2 = storageboxData[j];
				if (itemArchiveData2.itemData.id.Equals(id))
				{
					return itemArchiveData2;
				}
			}
			return null;
		}

		public uint GenerateItemIndex()
		{
			if (maxItemIndex == uint.MaxValue || maxItemIndex < 1000)
			{
				maxItemIndex = 1000u;
			}
			else
			{
				maxItemIndex++;
			}
			return maxItemIndex;
		}
	}
}
